package handler

import (
	"github.com/gin-gonic/gin"
	"github.com/lab-online/internal/class/constant"
	"github.com/lab-online/internal/class/entity"
	"github.com/lab-online/pkg/auth"
	mw "github.com/lab-online/pkg/middleware"
	"github.com/lab-online/pkg/resp"
	"github.com/lab-online/pkg/util"
)

type searchClassReqQuery struct {
	ID      uint   `form:"id" binding:"omitempty,min=0" example:"1"`                    // 班级ID
	Name    string `form:"name" binding:"omitempty,min=1,max=10" example:"高等数学1班"`      // 班级名称
	Teacher string `form:"teacher" binding:"omitempty,min=3,max=10" example:"20240205"` // 教师工号
	Student string `form:"student" binding:"omitempty,min=3,max=10" example:"20240205"` // 学生学号
}

var SearchClassValidator = mw.NewValidator(func() *mw.ValidatorOptions {
	return &mw.ValidatorOptions{
		Query: &searchClassReqQuery{},
	}
})

type teacherInfo = studentInfo
type searchClassRespData struct {
	ID          uint         `json:"id" binding:"required"`          // 班级ID
	Name        string       `json:"name" binding:"required"`        // 班级名称
	Teacher     *teacherInfo `json:"teacher" binding:"required"`     // 教师工号
	CourseID    uint         `json:"courseID" binding:"required"`    // 课程ID
	Description string       `json:"description" binding:"required"` // 班级介绍
}

type SearchClassRespBody struct {
	resp.BaseRespBody
	Data []searchClassRespData `json:"data" binding:"required"`
}

// SearchClass 搜索班级
//
//	@Summary				搜索班级
//	@Description			通过关键词搜索班级，支持班级ID、教师工号、学生学号
//	@Description.markdown	SearchClass
//	@Tags					class
//	@Accept					json
//	@Produce				json
//	@Security				bearer
//	@Param					Authorization	header		string				true	"`all`"
//	@Param					class			query		searchClassReqQuery	true	"班级信息"
//	@Success				200				{object}	SearchClassRespBody
//	@Failure				400				{object}	resp.FailedRespBodyString
//	@x-apifox-status		"developing"
//	@Router					/v1/classes	[get]
func (h *Handler) SearchClass(c *gin.Context) {
	query := c.MustGet(mw.KeyQuery).(*searchClassReqQuery)
	authEntity := c.MustGet(auth.KeyAuth).(auth.AuthEntity)
	queryEntity := entity.NewClassEntity(
		entity.WithID(query.ID),
		entity.WithTeacher(query.Teacher),
		entity.WithName(query.Name),
	)
	if query.Student != "" {
		queryEntity.UpdateEntity(entity.WithStudents(query.Student))
	}

	if classes, err := h.domain.SearchClass(queryEntity, authEntity); err != nil {
		resp.ErrorHandler(c, err)
	} else {
		resp.Success(c, constant.CodeSearchClassSuccess, util.SliceMap(classes,
			func(class entity.ClassEntity) *searchClassRespData {
				return &searchClassRespData{
					ID:          class.GetID(),
					Name:        class.GetName(),
					CourseID:    class.GetCourseID(),
					Description: class.GetDescription(),
					Teacher: &studentInfo{
						Username: class.GetTeacher(),
						Role:     class.GetTeacherVO().GetRole(),
						Name:     class.GetTeacherVO().GetName(),
					},
				}
			}),
		)
	}
}
